/* ---begin--对象联合类型--- */
{
  type Person = {
    name: string;
    age: number;
  };
    
  type Employee = {
    id: number;
  } & Person; // 继承Person
    
  type Student = {
    school: string;
    stuno: number;
  } & Person;
    
  type WorkerOrStudent = Employee | Student;

  /** 
   * type WorkerOrStudent = {
   *  name: string;
   *  age: number;
   *  id: number;
   *  school?: string;
   *  stuno?: number;
   * }
   * 或者
   * type WorkerOrStudent = {
   *  name: string;
   *  age: number;
   *  school: string;
   *  stuno: number;
   *  id?: number;
   * }
   * */
  // 此时满足的是Employee基类,此时school，stuno是可选参数
  const employee: WorkerOrStudent = {
    name: 'John Doe',
    age: 30,
    id: 12345,
    school: 'ABC University'
  };
  // 错误示范
  const emp: WorkerOrStudent = {
    name: 'John Doe',
    age: 30,
    //id: 12345,
    school: 'ABC University'
  };


  function fun(per: WorkerOrStudent) {
    // 错误示范
    console.log(per.id)
    // 正确方式
    if('id' in per) {
      console.log(per.id)
    }
  }
  // 注意此时，不是WorkerOrStudent类型，而是它的基类
  const employee2: Employee = {
    name: 'John Doe',
    age: 30,
    id: 12345
  };

  fun(employee2)

  /**
   * 1. 当满足任意一个基类（类型）时，其它参数都是可选的
   * 2. 当不确定是哪一个基类时，非公共成员都是可选参数，此时要使用typeof进行类型判断 (比如：作为方法的参数时)
   */
}

// 通过代码
// 当满足任意一个基类时，其它参数都是可选的
{

  type A = {
    id: number;
    name: string;
    age: number; 
  }

  type B = {
    age: string;
    sex: boolean;
  }

  type C = A | B;


  /**
   * 等同于
   * 此时满足A
   * type C = {
   *  id: number;
   *  name: string;
   *  age: number;
   *  sex?: boolean;
   * }
   * 或者
   * 此时满足B
   * type C = {
   *  age: string;
   *  sex: boolean;
   *  id?: number;
   *  name?: string; 
   * }
   * 
   */

  const obj1: C = {
    id: 7,
    name: 'ck',
    age: 18
  }
  const obj2: C = {
    id: 7,
    name: 'ck',
    age: 18,
    sex: true
  }
  const obj4: C = {
    age: '18',
    sex: true,
    id: 7,
    name: 'ck'
  }
}

{
  type A = {
    id: number;
    name: string;
    age: number; 
  }

  type B = {
    id?: number;
    school: string;
  }

  type C = A | B;

  /**
   * 等同于
   * 此时满足A
   * type C = {
   *  id: number;
   *  name: string;
   *  age: number;
   *  school?: boolean;
   * }
   * 或者
   * 此时满足B
   * type C = {
   *  id?: number;
   *  school: string; 
   *  age?: string;
   *  name?: boolean;
   * }
   * 
   */

  const obj1: C = {
    id: 7,
    name: 'ck',
    age: 18
  }
  const obj2: C = {
    id: 7,
    name: 'ck',
    age: 18,
    school: '国防科技'
  }
  const obj3: C = {
    school: '国防科技',
  }
  const obj4: C = {
    name: 'ck',
    age: 18,
    school: '国防科技'
  }
  const obj5: C = {
    id: 7,
    school: '国防科技',
  }
  const obj6: C = {
    id: 7,
    school: '国防科技',
    name: 'ck',
    age: 18,
  }
  

}

/* ---end--对象联合类型--- */

{
  // as const: 将表达式变为一个不可变（readonly）的字面量数据类型
  // earth数据类型：元组值数据类型
  const earth = ['sourth', 'east', 'west', 'north'] as const;
  // 利用typeof 获取earth 数据类型，并通过number关键字遍历
  type values = typeof earth[number]
}